#include "StdAfx.h"
#include "TcpIoLoop.h"

TcpIoLoop::TcpIoLoop() 
: isRunning(false), ioService_()
{
}

TcpIoLoop::~TcpIoLoop()
{
	Stop();
}

void TcpIoLoop::Start()
{
	if( isRunning == true )
		return;

    isRunning = true;

	ioService_.reset();

	SYSTEM_INFO sysinfo;
	::GetSystemInfo( &sysinfo );
	uint32_t double_of_cores = sysinfo.dwNumberOfProcessors*2;

	for(uint32_t i = 0; i < double_of_cores; ++i)
	{
		HANDLE thread = (HANDLE)::_beginthreadex(0, 0, threadCallback, (void*)this, 0, NULL);
		threadHandles_.push_back(thread);
	}
}

void TcpIoLoop::Stop()
{
	if( isRunning == false )
		return;

	isRunning = false;

	ioService_.stop();

	// assumed the number of thread is smaller than MAXIMUM_WAIT_OBJECTS.
	::WaitForMultipleObjects(threadHandles_.size(), &threadHandles_[0], true, INFINITE);
}

boost::asio::io_service& TcpIoLoop::Get()
{
	return ioService_;
}

uint32_t __stdcall TcpIoLoop::threadCallback(void* pv)
{
	if( pv )
		((TcpIoLoop*) pv)->Run();

	_endthreadex(0);
	return 0;
}

void TcpIoLoop::Run()
{
	while (isRunning)
	{
		ioService_.run();
	}
}
